/**   
* @Title: WorderToNewWordUtils.java 
* @Package cn.kxm.util 
* @Description: word生成工具
* @author 初雨泽
* @date 2018年10月8日 下午8:28:39   
*/
package cn.kxm.util;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

/** 
* @ClassName: WorderToNewWordUtils 
* @Description: word生成工具
* @author 初雨泽
* @date 2018年10月8日 下午8:28:39 
*  
*/
public class WorderToNewWordUtils {
	/** 
	* @Title: changWord 
	* @Description: 根据模板生成新的word文档，判断表格是需要替换还是插入
	* 判断逻辑有$为替换，表格无$为插入
	* @param inputUrl 模板存放地址
	* @param outputUrl 新文档存放地址
	* @param textMap 需要替换的信息集合
	* @param tableList 需要插入的表格信息集合
	* @return 成功返回true，失败返回false
	* @return boolean    返回类型 
	* @throws 
	*/
	public XWPFDocument changWord(FileInputStream in,
			Map<String,String> textMap,
			List<String[]> tableList,
			int cell_num) {
		//模板转换默认成功
		XWPFDocument document=null;
		
		try {
			//获取docx解析对象
			document= new XWPFDocument(in);
			/*//获取模板对象
			List<XWPFParagraph> allParagraph = document.getParagraphs();
			//输出模板内容
			StringBuffer tempText = new StringBuffer();
            for (XWPFParagraph xwpfParagraph : allParagraph) {
                    List<XWPFRun> runList = xwpfParagraph.getRuns();
                    for (XWPFRun xwpfRun : runList) {
                        tempText.append(xwpfRun.toString());
                    }
            }
            System.out.println("模板对象"+tempText.toString());
            //获取表格对象
            
            StringBuffer tableText = new StringBuffer();
            
            List<XWPFTable> allTable = document.getTables();
            
            for (XWPFTable xwpfTable : allTable) {
                //获取表格行数据
                List<XWPFTableRow> rows = xwpfTable.getRows();
                for (XWPFTableRow xwpfTableRow : rows) {
                    //获取表格单元格数据
                    List<XWPFTableCell> cells = xwpfTableRow.getTableCells();
                    for (XWPFTableCell xwpfTableCell : cells) {
                        List<XWPFParagraph> paragraphs = xwpfTableCell.getParagraphs();
                        for (XWPFParagraph xwpfParagraph : paragraphs) {
                            List<XWPFRun> runs = xwpfParagraph.getRuns();
                            for(int i = 0; i < runs.size();i++){
                                XWPFRun run = runs.get(i);
                                tableText.append(run.toString());
                            }
                        }
                    }
                }
            }
            System.out.println("表格对象："+tableText.toString());*/
            
			//解析替换文本段落对象
			this.changeText(document, textMap);
			//解析替换表格对象
			this.changeTable(document, textMap, tableList, cell_num);
			
		}catch(IOException e){
			e.printStackTrace();
		}
		return document;
	}
	/*
	*//** 
	* @Title: changeText 
	* @Description: 替换段落文本
	* @param document docx解析对象
	* @param textMap  需要替换的信息集合
	* @return void    返回类型 
	* @throws 
	*/
	public void changeText(XWPFDocument document, Map<String, String> textMap) {
		//获取段落集合
		List<XWPFParagraph> paragraphs= document.getParagraphs();
		
		for(XWPFParagraph paragraph:paragraphs) {
			//判断此段落时候需要进行替换
			String text=paragraph.getText();
			if(checkText(text)) {
				List<XWPFRun> runs=paragraph.getRuns();
				for(XWPFRun run:runs) {
					//替换模板原来位置
					run.setText(changeValue(run.toString(), textMap),0);
				}
			}
		}
	}
	
	/** 
	* @Title: changeTable 
	* @Description:替换表格对象方法 
	* @param document docx解析对象
	* @param textMap 需要替换的信息集合
	* @param tableList  需要插入的表格信息集合
	* @return void    返回类型 
	* @throws 
	*/
	public void changeTable(XWPFDocument document,Map<String,String> textMap,
			List<String[]> tableList,int cell_num) {
		//获取表格对象集合
		List<XWPFTable> tables=document.getTables();
		for(int i=0;i<tables.size();i++) {
			//只处理行数大于2的表格，且不循环表头
			XWPFTable table=tables.get(i);
			if(table.getRows().size()>1) {
				System.out.println("第"+i+"个表格");
				//判断表格是需要替换还是插入，判断逻辑有$为替换，表格无$为插入
				if(checkText(table.getText())) {
					System.out.println("第"+i+"是需要替换的表格");
					List<XWPFTableRow> rows=table.getRows();
					//遍历表格，并替换模板
					eachTable(rows,textMap);
				}else {
					System.out.println("第"+i+"是需要插入的表格");
					System.out.println("插入"+table.getText());
					insertTable(table,tableList,cell_num);
				}
			}
		}
	}
	
	/** 
	* @Title: eachTable 
	* @Description: 遍历表格
	* @param rows 表格行对象
	* @param textMap  需要替换的信息集合
	* @return void    返回类型 
	* @throws 
	*/
	public void eachTable(List<XWPFTableRow> rows,Map<String,String> textMap) {
		for(XWPFTableRow row:rows) {
			List<XWPFTableCell> cells=row.getTableCells();
			for(XWPFTableCell cell:cells) {
				//判断单元格是否需要替换
				if(checkText(cell.getText())) {
					List<XWPFParagraph> paragraphs=cell.getParagraphs();
					for(XWPFParagraph paragraph:paragraphs) {
						List<XWPFRun> runs=paragraph.getRuns();
						for(XWPFRun run:runs) {
							System.out.println("run.toString:"+run.toString());
							run.setText(changeValue(run.toString(),textMap),0);
						}
					}
				}
			}
		}
	}
	
	/** 
	* @Title: insertTable 
	* @Description: 为表格插入数据，行数不够添加新行
	* @param table 需要插入数据的表格
	* @param tableList 插入数据集合
	* @return void    返回类型 
	* @throws 
	*/
	public void insertTable(XWPFTable table,List<String[]> tableList,int cell_num) {
		//创建行，根据需要插入的数据添加新行，不处理表头
		System.out.println("tableList.size:"+tableList.size());
		for(int i=1;i<tableList.size();i++) {
			XWPFTableRow row=table.createRow();
			for(int j=0;j<cell_num;j++) {
				row.createCell();
			}
		}
		//遍历表格插入数据
		
		List<XWPFTableRow> rows=table.getRows();
		System.out.println("共有"+rows.size()+"行");
		for(int i=2;i<rows.size();i++) {
			XWPFTableRow newRow=table.getRow(i);
			List<XWPFTableCell> cells=newRow.getTableCells();
			System.out.println("第"+i+"行共有"+cells.size()+"个单元格");
			for(int j=0;j<cells.size();j++) {
				XWPFTableCell cell=cells.get(j);
				cell.setText(tableList.get(i-2)[j]);
			}
		}
	}
	
	/** 
	* @Title: checkText 
	* @Description: 判断文本中时候包含$
	* @param text 文本
	* @return  参数说明 包含返回true，不包含返回false
	* @return boolean    返回类型 
	* @throws 
	*/
	public boolean checkText(String text) {
		boolean check=false;
		if(text.indexOf("$")!=-1) {
			check=true;
		}
		System.out.println("checkText:"+check);
		return check;
	}
	
	/** 
	* @Title: changeValue 
	* @Description: 匹配传入信息集合与模板
	* @param value 模板需要替换的区域
	* @param textMap 传入信息集合
	* @return  参数说明  模板需要替换区域信息集合对应值
	* @return String    返回类型 
	* @throws 
	*/
	public String changeValue(String value,Map<String,String> textMap) {
		Set<Entry<String,String>> textSets=textMap.entrySet();
		for(Entry<String,String> textSet:textSets) {
			//匹配模板与替换值，格式${key}
			String key="${"+textSet.getKey()+"}";
			System.out.println("key:"+key);
			System.out.println("value:"+value);
			if(value.indexOf(key)!=-1) {
				value=textSet.getValue();
				System.out.println("value:"+value);
				System.out.println("the value will return!");
				//此处不返回，程序会出现错误
				return value;
			}
		}
		//模板未匹配到区域替换为空
		if(checkText(value)) {
			value="";
		}
		return value;
	}
	
	
	
	
}
